#ifndef RP2VECTOR4_H
#define RP2VECTOR4_H

#include "Rp2System.h"
#include "Rp2Vector3.h"

namespace Rp2
{

template <class Real>
class Vector4
{
public:
	// construction
	Vector4();
	Vector4 (Real fX, Real fY, Real fZ, Real fW);
	Vector4 (const Real* afTuple);
	Vector4 (const Vector4& rkV);
	Vector4 (const Vector3<Real>& rkV3, Real w);

	// coordinate access
	inline operator const Real* () const;
	inline operator Real* ();
	inline Real operator[] (int i) const;
	inline Real& operator[] (int i);
	inline Real X () const;
	inline Real& X ();
	inline Real Y () const;
	inline Real& Y ();
	inline Real Z () const;
	inline Real& Z ();
	inline Real W () const;
	inline Real& W ();

	// assignment
	inline Vector4& operator= (const Vector4& rkV);

	// comparison
	bool operator== (const Vector4& rkV) const;
	bool operator!= (const Vector4& rkV) const;
	bool operator<  (const Vector4& rkV) const;
	bool operator<= (const Vector4& rkV) const;
	bool operator>  (const Vector4& rkV) const;
	bool operator>= (const Vector4& rkV) const;

	// arithmetic operations
	inline Vector4 operator+ (const Vector4& rkV) const;
	inline Vector4 operator- (const Vector4& rkV) const;
	inline Vector4 operator* (Real fScalar) const;
	inline Vector4 operator/ (Real fScalar) const;
	inline Vector4 operator- () const;

	// arithmetic updates
	inline Vector4& operator+= (const Vector4& rkV);
	inline Vector4& operator-= (const Vector4& rkV);
	inline Vector4& operator*= (Real fScalar);
	inline Vector4& operator/= (Real fScalar);

	// vector operations
	inline Real Length () const;
	inline Real SquaredLength () const;
	inline Real Dot (const Vector4& rkV) const;
	inline Real Normalize ();

	static const Vector4 ZERO; //(0,0,0,0)
	static const Vector4 UNIT_X;
	static const Vector4 UNIT_Y;
	static const Vector4 UNIT_Z;
	static const Vector4 UNIT_W;
	static const Vector4 ONE; //(1,1,1,1)

	// debug
	void Print();

private:
	// support for comparisons
	int CompareArrays (const Vector4& rkV) const;

	Real m_afTuple[4];

};

#include "Rp2Vector4.inl"
typedef Vector4<float> Vector4f;
typedef Vector4<double> Vector4d;

}


#endif